﻿#region 引用
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;

using DevComponents.DotNetBar.Rendering;
using Kaixin001.Common;
using Kxzz.Common;
using KxzzEntity.UsersEntity;
using KxzzEntity.SettingEntity;

using Kaixin001.Friend;
using Kaixin001.Images;
using Kaixin001.UserUtil;
using Kaixin001.XmlUtil;
using Kaixin001.Security;
using Kxzz.Enums;
using Kaixin001.Garden;
using Kxzz.IconUtil;
using KxzzEntity.FriendsEntity;
#endregion

namespace Kxzz
{
    public partial class frmLogin : DevComponents.DotNetBar.Office2007Form
    {
        #region 变量
        /// <summary>
        /// 登录线程
        /// </summary>
        Thread loginThread;

        delegate void DelegateShowMessage(string str);
        delegate void DelegateVoid();
        delegate void DelegateSetUserHead(Image image);
        DelegateShowMessage showLoadNetFriendStatus;

        private bool blnNeedVerify = false;
        private UserInfoEntity userInfo = null;
        private HttpSettingEntity httpSetting = new HttpSettingEntity();
        private List<LoginSettingEntity> loginSettings = new List<LoginSettingEntity>();
        private object inputVerifyLocker = new object();
        private IniHelper iniHelper = new IniHelper(Application.StartupPath + "//Config//config.ini");
        #endregion

        #region 初始化
        public frmLogin()
        {
            InitializeComponent();
        }
        private void frmLogin_Load(object sender, EventArgs e)
        {
            //初始化窗体数据
            #region 初始化界面
            if (this.iniHelper.read("Setup", "skin") != "")
            {
                eOffice2007ColorScheme colorScheme = (eOffice2007ColorScheme)Enum.Parse(typeof(eOffice2007ColorScheme), this.iniHelper.read("Setup", "skin"));
                this.Office2007ColorTable = colorScheme;
            }

            this.Size = new System.Drawing.Size(Init.FormWidth, Init.FormHeight);
            //base.Location = new Point(
            //    Screen.PrimaryScreen.WorkingArea.Width - base.Width - 145,
            //    Screen.PrimaryScreen.WorkingArea.Height - base.Height - 40);
            Init.initPoint = base.Location;
            #endregion

            this.FormInit();
            this.Show();
            this.tbdEmail.Focus();
        }
        #endregion 

        #region 界面操作
        private void frmLogin_LocationChanged(object sender, EventArgs e)
        {
            Init.initPoint = this.Location;
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            NeedVerifyCode();
            txtVerifyCode.Focus();
        }

        private void frmLogin_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.timerLogin.Enabled = false;
            //不为更改用户状态，让程序结束
            this.notifyIconLogin.Dispose();
            Init.setAttribute("Logout", false);
        }

        private void btnLogon_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.btnLogon.Text == "登录")
                {
                    this.timerLogin.Enabled = true;

                    if (string.IsNullOrEmpty(this.tbdEmail.Text.Trim()) ||
                       string.IsNullOrEmpty(this.txtPassWord.Text.Trim()))
                    {
                        DevComponents.DotNetBar.MessageBoxEx.Show(
                            "请输入完整的帐号信息！",
                            "提示",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);
                        return;
                    }

                    LoginView();

                    #region 用户登录
                    this.Login();
                    #endregion
                }
                else if (this.btnLogon.Text == "取消")
                {
                    this.CanelLoginView();
                }
            }
            catch (Exception ex)
            {
                DevComponents.DotNetBar.MessageBoxEx.Show(
                           ex.Message,
                           "提示",
                           MessageBoxButtons.OK,
                           MessageBoxIcon.Error);
            }
        }

        private void lbNetworkSetting_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            frmSetting formSetting = new frmSetting(SettingMode.Proxy);
            formSetting.Show();
        }

        private void tbdEmail_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                //在选择帐号时并配置帐号相关信息显示到控件

                if (this.tbdEmail.SelectedItem == null)
                {
                    return;
                }

                LoginSettingEntity loginSetting = this.tbdEmail.SelectedItem as LoginSettingEntity;
                if (loginSetting == null)
                {
                    return;
                }

                //如果编号不等于空则加载用户信息
                if (loginSetting.Uid != null || loginSetting.Uid != "")
                {
                    this.riDefaultImage.Image = UserHelper.GetUserHead(loginSetting.Uid);
                }
                this.txtPassWord.Text = SecurityHelper.DecryptDES(loginSetting.Password, Init.EncodeKey);
                this.cbAutoLogin.Checked = loginSetting.AutoLogin;
                this.cbRemeberAccount.Checked = loginSetting.RememberPassword;

                if (loginSetting.AutoLogin)
                {
                    LoginView();
                    this.Login();
                }
            }
            catch (Exception ex)
            {
                DevComponents.DotNetBar.MessageBoxEx.Show(
                        ex.Message,
                        "错误",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
            }
        }

        private void timerLogin_Tick(object sender, EventArgs e)
        {
            IconHelper iconHelper = new IconHelper();
            iconHelper.ShowLogin(this.notifyIconLogin);
        }
        #endregion

        #region Private Method
        /// <summary>
        /// 用户登录
        /// </summary>
        private void Login()
        {
            try
            {
                loginThread = new Thread(LoginAndLoadingInfo);
                loginThread.Start();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 显示登录状态
        /// </summary>
        /// <param name="msg">状态信息</param>
        private void ShowStatus(string msg)
        {
            this.lblNetworkingStatus.Text = msg;
        }

        /// <summary>
        /// 输入验证码
        /// </summary>
        /// <param name="accountHelper">账号信息</param>
        /// <returns></returns>
        private void NeedVerifyCode()
        {
            lock (inputVerifyLocker)
            {
                this.panelLogin.Visible = false;
                this.panelVerify.Visible = true;
                this.btnLogon.Text = "登录";
                this.pictureBox1.Image = Init.Kaixin001Helper.GetVerifyCode();
            }
        }

        /// <summary>
        /// 取消显示验证码框
        /// </summary>
        private void CancelVerifyView()
        {
            lock (inputVerifyLocker)
            {
                this.panelLogin.Visible = false;
                this.panelVerify.Visible = false;
                this.blnNeedVerify = false;
            }
        }

        /// <summary>
        /// 设置用户头像
        /// </summary>
        /// <param name="image"></param>
        private void SetUserHead(Image image)
        {
            this.riDefaultImage.Image.Dispose();
            this.riDefaultImage.Image = image;
        }

        /// <summary>
        /// 保存好友头像到本地
        /// </summary>
        /// <param name="i"></param>
        private void SaveFriendsHead(int i)
        {
            ImagesHelper imagesHelper = new ImagesHelper();

            if(!Directory.Exists(Init.FriendsHeadFolder))
            {
                Directory.CreateDirectory(Init.FriendsHeadFolder);
            }

            if (!File.Exists(Init.OnlineFriends[i].LocalIcon))
            {
                imagesHelper.SaveImage(Init.OnlineFriends[i].Icon, Init.OnlineFriends[i].LocalIcon,new Size(20,20));
            }
        }

        /// <summary>
        /// 登录获取好友信息
        /// </summary>
        private void LoginAndLoadingInfo()
        {
            DelegateVoid canelLoginView = new DelegateVoid(CanelLoginView);
            try
            {
                #region Login
                showLoadNetFriendStatus = new DelegateShowMessage(ShowStatus);

                #region 用户登录
                this.BeginInvoke(showLoadNetFriendStatus, new object[] { "正在登录..." });
                try
                {
                    if (!blnNeedVerify)
                    {
                        this.userInfo = Init.Kaixin001Helper.Login(this.tbdEmail.Text.Trim(), this.txtPassWord.Text.Trim());
                    }
                    else
                    {
                        DelegateVoid cancelVerifyView = new DelegateVoid(this.CancelVerifyView);
                        this.BeginInvoke(cancelVerifyView);
                        this.userInfo = Init.Kaixin001Helper.Login(this.tbdEmail.Text.Trim(), this.txtPassWord.Text.Trim(), this.txtVerifyCode.Text.Trim());
                    }
                }
                catch (NeedVerifyCodeException)
                {
                    blnNeedVerify = true;
                    DelegateVoid needVerifyCode = new DelegateVoid(NeedVerifyCode);
                    this.BeginInvoke(needVerifyCode);
                    this.BeginInvoke(showLoadNetFriendStatus, new object[] { "需要输入验证码！" });
                    StopThead();
                    return;
                }
                catch (VerifyCodeInvalidException)
                {
                    this.BeginInvoke(showLoadNetFriendStatus, new object[] { "验证码错误，请重新输入！" });
                    blnNeedVerify = true;
                    DelegateVoid needVerifyCode = new DelegateVoid(NeedVerifyCode);
                    this.BeginInvoke(needVerifyCode);
                    StopThead();
                    return;
                }
                catch (Exception ex)
                {
                    this.BeginInvoke(showLoadNetFriendStatus, new object[] { ex.Message });
                    this.BeginInvoke(canelLoginView);
                    StopThead();
                    return;
                }
                #endregion

                if (this.userInfo != null)
                {
                    //登录成功
                    Init.setAttribute("LoginState", true);

                    #region 用户信息
                    //加载用户头像信息
                    this.BeginInvoke(showLoadNetFriendStatus, new object[] { "登录成功，加载用户信息..." });

                    UserHelper userHelper = new UserHelper();
                    Image userHeadImage = userHelper.SaveUserHead(userInfo);

                    //如果加载头像失败则把默认头像复制到用户数据目录
                    if (userHeadImage == null)
                    {
                        //先检测是否存在用户数据文件夹
                        userHelper.ExistsUserDataFolder(userInfo.Uid);

                        if (!File.Exists(".\\" + Init.UserDataFolder + "\\" + userInfo.Uid + "\\" + Init.UserUserHeadFileName))
                        {
                            File.Copy(Init.DefaultUserHeadPath, ".\\" + Init.UserDataFolder + "\\" + userInfo.Uid + "\\" + Init.UserUserHeadFileName);
                        }
                    }
                    else
                    {
                        this.BeginInvoke(new DelegateSetUserHead(this.SetUserHead), new object[] { userHeadImage });
                    }
                    //存储头像
                    Init.setAttribute("UserUserHeadImage", userHeadImage);
                    #endregion

                    #region 加载好友信息
                    this.BeginInvoke(showLoadNetFriendStatus, new object[] { "开始加载好友..." });

                    //开心网好友操作对象
                    FriendHelper friendHelper = new FriendHelper(Init.Kaixin001Helper.HttpSetting, Init.Kaixin001Helper.Cookies);
                    friendHelper.User = Init.Kaixin001Helper.User;
                    //得到所有好友分组，分组内并包含着好友
                    Init.FriendGroups = friendHelper.FindFriendGroups();

                    //全部好友
                    Init.AllFriends = friendHelper.GetAll();

                    foreach (FriendEntity friend in Init.AllFriends)
                    {
                        Init.AllFriendsDetail.Add(friend.Uid, friend);
                    }
                    //在线好友
                    Init.OnlineFriends = friendHelper.FindOnlineFriends();

                    //threads = new Thread[ProgramInit.AllFriends.Count];

                    this.BeginInvoke(showLoadNetFriendStatus, new object[] { "加载好友信息..." });

                    for (int i = 0; i < Init.OnlineFriends.Count; i++)
                    {
                        if (!File.Exists(Init.OnlineFriends[i].LocalIcon))
                        {
                            this.Invoke(showLoadNetFriendStatus, new object[] { i.ToString() + "/" + Init.OnlineFriends.Count.ToString() });
                            SaveFriendsHead(i);
                        }
                    }
                    #endregion

                    #region 用户登录信息

                    LoginSettingEntity loginSetting = new LoginSettingEntity();
                    loginSetting.Account = this.tbdEmail.Text.Trim();
                    loginSetting.Password = this.txtPassWord.Text.Trim();
                    loginSetting.RememberPassword = this.cbRemeberAccount.Checked;
                    loginSetting.AutoLogin = this.cbAutoLogin.Checked;
                    loginSetting.Uid = this.userInfo.Uid;

                    //存储该用户登录信息
                    this.SaveLoginSetting(loginSetting);
                    Init.setAttribute("LoginSetting", loginSetting);

                    #endregion

                    lcLogin.Active = false;
                    lcLogin.Enabled = false;
                    DelegateVoid closeThisForm = new DelegateVoid(CloseThisForm);
                    this.BeginInvoke(closeThisForm);
                }
                else
                {
                    this.BeginInvoke(canelLoginView);
                    this.BeginInvoke(showLoadNetFriendStatus, new object[] { "登录失败，请检查用户密码！" });
                }

                //StopThead();
                #endregion
            }
            catch (Exception ex)
            {
                this.BeginInvoke(canelLoginView);
                this.BeginInvoke(showLoadNetFriendStatus, new object[] {ex.Message });
                this.StopThead();
                ExceptionHelper.SaveLog("LoginAndLoadingInfo", ex);
            }
        }

        private void StopThead()
        {
            if (this.loginThread != null)
            {
                this.loginThread.Join();
                this.loginThread.Abort();
            }
        }

        /// <summary>
        /// 关闭该窗口
        /// </summary>
        private void CloseThisForm()
        {
            this.Close();
        }

        #region 初始化配置
        /// <summary>
        /// 初始化窗体
        /// </summary>
        private void FormInit()
        {
            this.riDefaultImage.Size = new Size(120, 120);

            Init.setAttribute("LoginState", false);
            CheckForIllegalCrossThreadCalls = false;

            httpSetting.Encoding = Encoding.UTF8;
            httpSetting.ContentType = "application/x-www-form-urlencoded";
            httpSetting.Referer = "http://www.kaixin001.com/";
            httpSetting.Accept = "application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-silverlight, */*";
            httpSetting.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; CIBA)";
            httpSetting.Timeout = 60 * 1000;
            httpSetting.Retry = 5;
            
            //设置开心网主操作对象
            Init.Kaixin001Helper = new Kaixin001Http(httpSetting);

            this.InitAccount();
            this.InitProxy();
            this.InitNomalSetting();

            //获取最后登录用户头像

            Image image =  null;

            if (File.Exists(iniHelper.read("UserHead", "LastLoginUserHead")))
            {
                image = Image.FromFile(iniHelper.read("UserHead","LastLoginUserHead"));
            }

            if (image == null)
            {
                //初始化默认头像
                if (File.Exists(Init.DefaultUserHeadPath))
                {
                    image = Image.FromFile(Init.DefaultUserHeadPath);
                }
                else
                {
                    image = Kxzz.Properties.Resources.Default;
                }
            }

            if (image != null)
            {
                Bitmap bitMap = new Bitmap(image, this.riDefaultImage.Size);
                this.riDefaultImage.Image = bitMap;
            }

            //最后一个索引肯定是最后一次被存储的帐号
            if (this.tbdEmail.Items.Count != 0)
            {
                this.tbdEmail.SelectedIndex = this.tbdEmail.Items.Count - 1;
            }
        }

        /// <summary>
        /// 初始化代理信息
        /// </summary>
        private void InitProxy()
        {
            if (File.Exists(Init.ProxySettingPath))
            {
                ProxySettingEntity proxyEntity = XmlHelper.XmlDeserialize(Init.ProxySettingPath, typeof(ProxySettingEntity)) as ProxySettingEntity;

                if (proxyEntity != null)
                {
                    if (proxyEntity.ProxyType != 0)
                    {
                        Init.Kaixin001Helper.Proxy = proxyEntity;
                    }
                    else
                    {
                        Init.Kaixin001Helper.Proxy = null;
                    }
                }
                else
                {
                    Init.Kaixin001Helper.Proxy = null;
                }
            }
        }

        /// <summary>
        /// 读取基本设置
        /// </summary>
        private void InitNomalSetting()
        {
            if (File.Exists(Init.NomalSettingPath))
            {
                Init.nomalSettingEntity = XmlHelper.XmlDeserialize(Init.NomalSettingPath, typeof(NomalSettingEntity)) as NomalSettingEntity;

                if (Init.nomalSettingEntity != null)
                {
                    Init.Kaixin001Helper.HttpSetting.Retry = Init.nomalSettingEntity.RetryTimes;
                    Init.Kaixin001Helper.HttpSetting.Timeout = Init.nomalSettingEntity.Timeout * 1000;
                }
                else
                {
                    Init.Kaixin001Helper.HttpSetting.Retry = 5;
                    Init.Kaixin001Helper.HttpSetting.Timeout = 30 * 1000;
                }
            }
        }

        /// <summary>
        /// 加载登录信息
        /// </summary>
        private void InitAccount()
        {
            this.tbdEmail.DisplayMember = "Account";
            this.tbdEmail.ValueMember = "Password";

            if(!Directory.Exists(Init.ConfigFolder))
            {
                Directory.CreateDirectory(Init.ConfigFolder);
            }

            if (!File.Exists(Init.LoginSettingPath))
            {
                File.Create(Init.LoginSettingPath);
            }

            //如果存在登录信息文件则读取信息
            if (File.Exists(Init.LoginSettingPath))
            {
                this.loginSettings = XmlHelper.XmlDeserialize(Init.LoginSettingPath, typeof(List<LoginSettingEntity>)) as List<LoginSettingEntity>;
                if (this.loginSettings != null)
                {
                    for (int i = 0; i < loginSettings.Count; i++)
                    {
                        LoginSettingEntity temp = loginSettings[i];
                        this.tbdEmail.Items.Add(temp);
                    }
                }
                else
                {
                    this.loginSettings = new List<LoginSettingEntity>();
                }
            }
        }

        /// <summary>
        /// 保存登录信息
        /// </summary>
        /// <param name="loginSetting"></param>
        private void SaveLoginSetting(LoginSettingEntity loginSetting)
        {
            LoginSettingEntity searchSetting = this.FindLoginSettingByAccount(loginSetting.Account);

            //密码加密
            loginSetting.Password = SecurityHelper.EncryptDES(loginSetting.Password, Init.EncodeKey);
            if (!loginSetting.RememberPassword)
            {
                loginSetting.Password = "";
            }
            if (searchSetting != null)
            {
                if (searchSetting.Password == loginSetting.Password && 
                    searchSetting.RememberPassword == loginSetting.RememberPassword && 
                    searchSetting.AutoLogin == loginSetting.AutoLogin && 
                    searchSetting.Uid == loginSetting.Uid)
                {
                    return;
                }
                else
                {
                    this.loginSettings.Remove(searchSetting);
                }
            }
            this.loginSettings.Add(loginSetting);
            XmlHelper.XmlSerialize(Init.LoginSettingPath, this.loginSettings, typeof(List<LoginSettingEntity>));
        }

        /// <summary>
        /// 通过帐号获取登录配置信息
        /// </summary>
        /// <param name="account"></param>
        /// <returns></returns>
        public LoginSettingEntity FindLoginSettingByAccount(string account)
        {
            foreach (LoginSettingEntity temp in loginSettings)
            {
                if (temp.Account == account)
                {
                    return temp;
                }
            }
            return null;
        }
        #endregion

        private void LoginView()
        {
            #region 登录界面
            this.btnLogon.Text = "取消";
            this.panelLogin.Visible = false;
            this.lcLogin.Visible = true;
            this.lcLogin.Active = true;
            this.lbNetworkSetting.Visible = false;
            #endregion
        }

        private void CanelLoginView()
        {
            #region 取消登录界面
            this.btnLogon.Text = "登录";
            this.panelLogin.Visible = true;
            this.lcLogin.Visible = false;
            this.lcLogin.Active = false;
            this.lbNetworkSetting.Visible = true;
            #endregion
        }
        #endregion
    }
}
